package com.example.mq.mqserver.datacenter;

import com.example.mq.common.MqException;
import com.example.mq.mqserver.core.Binding;
import com.example.mq.mqserver.core.Exchange;
import com.example.mq.mqserver.core.MSGQueue;
import com.example.mq.mqserver.core.Message;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 封装 内存数据的相关操作
 */
public interface IMemoryDataCenter {

    /**
     * 在内存中添加交换机
     * @param exchange 交换机
     */
    void insertExchange(Exchange exchange);
    /**
     * 通过交换机名，获取内存中的交换机
     * @param exchangeName 交换机名
     * @return
     */
    Exchange getExchange(String exchangeName);
    /**
     * 通过交换机名，删除内存中的交换机
     * @param exchangeName 交换机名
     */
    void deleteExchange(String exchangeName);


    /**
     * 在内存中，添加队列
     * @param queue 队列
     */
    void insertQueue(MSGQueue queue);
    /**
     * 通过队列名，获取内存中的队列
     * @param queueName 队列名
     * @return
     */
    MSGQueue getQueue(String queueName);
    /**
     * 通过队列名，删除内存中的队列
     * @param queueName 队列名
     */
    void deleteQueue(String queueName);


    /**
     * 在内存中添加一个绑定
     * @param binding 绑定
     */
    void insertBinding(Binding binding) throws MqException;
    /**
     * 获取内存中的唯一绑定
     * @param exchangeName 绑定中的交换机名
     * @param queueName 绑定中的队里名
     * @return
     */
    Binding getBinding(String exchangeName,String queueName);
    /**
     * 获取内存中，一个交换机对应的所有绑定
     * @param exchangeName 交换机名
     * @return key=exchangeName,value=Binding
     */
    ConcurrentHashMap<String,Binding> getBindings(String exchangeName);

    /**
     * 删除内存中的绑定关系
     * @param binding 绑定
     */
    void deleteBinding(Binding binding);

    /**
     * 在内存里保存一条消息
     * @param message 消息
     */
    void addMessage(Message message);
    /**
     * 通过消息Id，获取内存中的一条消息
     * @param messageId 消息Id
     * @return
     */
    Message getMessage(String messageId);
    /**
     * 通过消息Id，删除内存中的一条消息
     * @param messageId 消息Id
     */
    void removeMessage(String messageId);


    /**
     * 在内存中，将消息添加到队列
     * @param queueName 目标队列名
     * @param message 消息
     */
    void offerMessage(String queueName,Message message);
    /**
     * 在内存中，把消息移出队列
     * @param queueName 队列名
     * @return 队列的头消息
     */
    Message pollMessage(String queueName);
    /**
     * 获取内存中队列里的消息个数
     * @param queueName 队列名
     * @return
     */
    int getQueueSize(String queueName);


    /**
     * 当消息从队列中移除时，把消息添加进待确认消息集合中
     * @param queueName 队列名
     * @param message 消息
     */
    void addMessageWaitAck(String queueName,Message message);

    /**
     * 当消息被消费者消费时，移除队列中的待确认消息
     * @param queueName 队列名
     * @param messageId 消息Id
     */
    Message removeMessageWaitAck(String queueName,String messageId);


    /**
     * 恢复硬盘上的所有数据
     * @param diskDataCenter
     */
    void recovery(IDiskDataCenter diskDataCenter) throws IOException, ClassNotFoundException;
}
